//
//  UPNetworkManager.m
//  Uang Pasti
//
//  Created by 李永彬 on 2025/8/16.
//

#import "UPNetworkManager.h"

@interface UPNetworkManager ()

@property (nonatomic, strong) AFHTTPSessionManager *sessionManager;
@property (nonatomic, strong) NSMutableDictionary *commonHeaders;

@end

@implementation UPNetworkManager

+ (instancetype)sharedManager {
    static UPNetworkManager *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[UPNetworkManager alloc] init];
    });
    return instance;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _sessionManager = [AFHTTPSessionManager manager];
        _sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
        _sessionManager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"text/plain", nil];
        _commonHeaders = [NSMutableDictionary dictionary];
    }
    return self;
}

#pragma mark - 域名处理

- (NSString *)baseURLForDomainType:(UPDomainType)domainType {
    switch (domainType) {
        case UPDomainTypeDefault:
            return kDefaultDomain;
        case UPDomainTypeH5:
            return kH5Domain;
        default:
            return kDefaultDomain;
    }
}

- (NSString *)absoluteURLWithPath:(NSString *)path
                       domainType:(UPDomainType)domainType {
    return [[self baseURLForDomainType:domainType] stringByAppendingPathComponent:path];
}

#pragma mark - 请求头设置
- (void)setupRequestSerializerForType:(UPFieldHeaderContentType)serializerType {
    switch (serializerType) {
        case UPFieldHeaderContentTypeJSON:
            _sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
            break;
        case UPFieldHeaderContentTypeFormURLEncoded:
            _sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
            break;
        case UPFieldHeaderContentTypeFormData:
            _sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
            break;
    }
}

- (NSDictionary *)commonParameters {
    NSString *deviceModelName = [[UIDevice currentDevice] modelName];
    NSString *sessionId = [UPUserDefaults stringForKey: loginSessionIdKey];

    return @{
        @"skeptpersonast": @"ios",                // 终端版本
        @"onto": @"1.0.0",            // App版本
        @"caleeur": deviceModelName ?: @"",  // 设备名称
        @"rhinel": getIDFVForKey() ?: @"",         // IDFV
        @"acrilike": [[UIDevice currentDevice] systemVersion] ?: @"", // 设备OS版本
        @"never": @"siap-dana",         // 市场
        @"aroundan": sessionId ?: @"",            // 会话ID
        @"visiting": getIDFVForKey() ?: @"",                 // IDFV
        @"othersary": [AppConfig sharedInstance].countryId ?: @""                // 当前国家ID
    };
}

- (void)setHttpHeaders:(UPFieldHeaderContentType)contentType {
    
    NSString *headerValueStr = nil;
    
    switch (contentType) {
        case UPFieldHeaderContentTypeJSON:
            headerValueStr = @"application/json";
            break;
            
        case UPFieldHeaderContentTypeFormURLEncoded:
            headerValueStr = @"application/x-www-form-urlencoded";
            break;
            
        case UPFieldHeaderContentTypeFormData:
            headerValueStr = @"multipart/form-data";
            break;
            
        default:
            break;
    }
    
    [_sessionManager.requestSerializer setValue: headerValueStr
                             forHTTPHeaderField:@"Content-Type"];
}

#pragma mark - 请求方法

- (NSURLSessionDataTask *)GET:(NSString *)path
                   domainType:(UPDomainType)domainType
                       params:(NSDictionary *)params
                  contentType:(UPFieldHeaderContentType)contentType
                     callback:(UPRequestCallback)callback {
    
    [self setupRequestSerializerForType:contentType];
    [self setHttpHeaders:contentType];
    
    NSString *baseURL = [self absoluteURLWithPath:path domainType:domainType];
    NSString *url = [NSString stringWithFormat:@"%@?%@", baseURL, [self commonParameters].dicToURLQueryStr];
    
    return [self.sessionManager GET:url
                         parameters:params
                            headers:nil
                           progress:nil
                            success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        if (success) success(responseObject);
        [self handleSuccessResponse:responseObject callback:callback];
    }
                            failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        if (failure) failure(error);
        [self handleError:error callback:callback];
    }];
}

- (NSURLSessionDataTask *)POST:(NSString *)path
                    domainType:(UPDomainType)domainType
                        params:(NSDictionary *)params
                   contentType:(UPFieldHeaderContentType)contentType
                      callback:(UPRequestCallback)callback {
    
    [self setupRequestSerializerForType:contentType];
    [self setHttpHeaders:contentType];
    
    NSString *baseURL = [self absoluteURLWithPath:path domainType:domainType];
    NSString *url = [NSString stringWithFormat:@"%@?%@", baseURL, [self commonParameters].dicToURLQueryStr];
    
    return [self.sessionManager POST:url
                          parameters:params
                             headers:nil
                            progress:nil
                             success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        if (success) success(responseObject);
        [self handleSuccessResponse:responseObject callback:callback];
    }
                             failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        if (failure) failure(error);
        [self handleError:error callback:callback];
    }];
}

- (NSURLSessionDataTask *)upload:(NSString *)path
                      domainType:(UPDomainType)domainType
                          params:(NSDictionary *)params
                        fileData:(NSData *)fileData
                            name:(NSString *)name
                        fileName:(NSString *)fileName
                        mimeType:(NSString *)mimeType
                        progress:(void (^)(NSProgress *))progress
                        callback:(UPRequestCallback)callback {
    
    [self setupRequestSerializerForType: UPFieldHeaderContentTypeFormData];
    [self setHttpHeaders: UPFieldHeaderContentTypeFormData];
    
    NSString *baseURL = [self absoluteURLWithPath:path domainType:domainType];
    NSString *url = [NSString stringWithFormat:@"%@?%@", baseURL, [self commonParameters].dicToURLQueryStr];
    
    return [self.sessionManager POST:url
                          parameters:params
                             headers:nil
           constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        [formData appendPartWithFileData:fileData
                                    name:name
                                fileName:fileName
                                mimeType:mimeType];
    }
                            progress:^(NSProgress * _Nonnull uploadProgress) {
        if (progress) progress(uploadProgress);
    }
                             success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        if (success) success(responseObject);
        [self handleSuccessResponse:responseObject callback:callback];
    }
                             failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        if (failure) failure(error);
        [self handleError:error callback:callback];
    }];
}

- (void) handleSuccessResponse:(id)responseObject callback:(UPRequestCallback)callback
{
    NSData *data = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingFragmentsAllowed error:nil];
    NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"response: %@", jsonString);
    UPResponse *response = [UPResponse responseWithObject:responseObject];
    
    switch (response.lotfication) {
        case -2:
            [[NSNotificationCenter defaultCenter] postNotificationName:kLogOutOrExpiredNotificationKey object:nil userInfo:nil];
            break;
        default:
            break;
    }
    
    [self finishRequest:response callback:callback];
}

- (void) handleError:(NSError *)error callback:(UPRequestCallback)callback
{
    UPResponse *response = [UPResponse responseWithError:error];
    [self finishRequest:response callback:callback];
}

- (void) finishRequest:(UPResponse *)response callback:(UPRequestCallback)callback
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (callback)
        {
            callback(response);
        }
    });
}

@end
